#include "widget.h"
#include "GL/gl.h"
#include <QImage>

#define BUFFER_OFFSET(offset) ((void*) (offset))

Widget::Widget()
{
    setWindowTitle("纹理");
}

Widget::~Widget()
{

}

void Widget::initializeGL()
{
    initializeOpenGLFunctions();

    glEnable(GL_TEXTURE_2D);

    m_program = new QOpenGLShaderProgram(this);

    //编译代码-添加顶点着色器
    m_program->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/triangles.vert");
    //编译代码-添加片段着色器
    m_program->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/triangles.frag");

    //链接着色器
    m_program->link();

    //VAO，VBO数据部分
    float vertices[] = {
    //     ---- 位置 ----       ---- 颜色 ----     - 纹理坐标 -
         0.5f,  0.5f, 0.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f,   // 右上
         0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,   1.0f, 0.0f,   // 右下
        -0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f,   // 左下
        -0.5f,  0.5f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 1.0f    // 左上
    };

    unsigned int indices[] = { // 注意索引从0开始!
        0, 1, 3, // 第一个三角形
        1, 2, 3  // 第二个三角形
    };

    //得到顶点属性名在着色器参数列表中的位置-0
    m_posAttr = m_program->attributeLocation("aPos");
    m_colorAttr = m_program->attributeLocation("aColor");
    m_texCoordAttr = m_program->attributeLocation("aTexCoord");

    glGenVertexArrays(1, m_VAO);
    glBindVertexArray(m_VAO[0]);

    glGenBuffers(1, m_VBO);
    glBindBuffer(GL_ARRAY_BUFFER, m_VBO[0]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    //链接顶点属性
    glVertexAttribPointer(m_posAttr, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), BUFFER_OFFSET(0));
    glVertexAttribPointer(m_colorAttr, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), BUFFER_OFFSET(3*sizeof(GLfloat)));
    glVertexAttribPointer(m_texCoordAttr, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), BUFFER_OFFSET(6*sizeof(GLfloat)));

    glEnableVertexAttribArray(m_posAttr);
    glEnableVertexAttribArray(m_colorAttr);
    glEnableVertexAttribArray(m_texCoordAttr);

    //索引缓冲对象
    glGenBuffers(1, m_EBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_EBO[0]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    //解绑缓存着色器（绑定和解绑的顺序很重要，勿更改）
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    //生成纹理
    m_textureBg = new QOpenGLTexture(QImage(":/wall.jpg").mirrored());
    m_textureBg->setMinificationFilter(QOpenGLTexture::LinearMipMapLinear);
    m_textureBg->setMagnificationFilter(QOpenGLTexture::Linear);

}

void Widget::resizeGL(int w, int h)
{
    glViewport(0, 0, w, h);
}

void Widget::paintGL()
{
    glClearColor(0.2f, 0.3f, 0.3f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    m_program->bind();

    glBindVertexArray(m_VAO[0]);

    m_textureBg->bind();

    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

    m_textureBg->release();
    m_program->release();
}
